﻿#pragma once

#include "../csv/csv_reader.hh"
#include "../util/box_std_allocator.hh"
#include "../util/object_pool.hh"
#include "../util/spsc_queue.hpp"
#include <atomic>
#include <fstream>
#include <string>
#include <thread>
#include <vector>

namespace kratos {
namespace service {
class ServiceBox;
}
} // namespace kratos

namespace kratos {
namespace util {

class ResultImpl;
class CursorImpl;
class CsvRowImpl;
class CsvLoaderImpl;
class CsvReaderDefault;

/**
 * 字段数组.
 */
using FieldVector = kratos::service::PoolVector<std::string>;
using StringVector =
    std::vector<std::string, kratos::service::Allocator<std::string>>;
using SearchResult =
    std::vector<StringVector, kratos::service::Allocator<StringVector>>;

enum class CsvState {
  UnQuoted,
  QuotedHead,
  QuotedTail,
};

/**
 * CSV行实现.
 */
class CsvRowImpl : public CsvRow {
  FieldVector field_vec_; ///< 数据

public:
  /**
   * 构造.
   *
   * \param field_vec 数据
   */
  CsvRowImpl(const FieldVector &field_vec);
  /**
   * 析构.
   *
   */
  virtual ~CsvRowImpl();
  virtual auto get(std::size_t col, std::string &value) const noexcept
      -> bool override;
};

/**
 * CSV加载器实现.
 */
class CsvLoaderImpl : public CsvLoader {
  using RowVector = kratos::service::PoolVector<CsvRowImpl *>;

  std::time_t last_update_ts_{0}; ///< 上一次更新的时间戳，秒
  std::size_t skip_line_{0};      ///< 需要跳过的行数
  std::string file_path_;         ///< 文件路径
  std::string last_error_;        ///< 最新的错误
  bool is_auto_reload_{true};     ///< 是否自动热加载
  int cur_lineno_{1};             ///< 当前解析的行号
  std::size_t column_{0};         ///< 列数量
  bool file_loaded_{false};       ///< 是否已经正常加载
  RowVector row_vec_;             ///< 正在使用的数据
  RowVector new_vec_;             ///< 用于热加载的数据
  kratos::service::ServiceBox *box_{nullptr}; ///< 服务容器
  CsvState csv_state_{CsvState::UnQuoted};    ///< csv解析器的状态

public:
  /**
   * 构造.
   *
   */
  CsvLoaderImpl();
  /**
   * 析构.
   *
   */
  virtual ~CsvLoaderImpl();
  virtual auto load(const std::string &file_path, std::size_t skip_line)
      -> bool override;
  virtual auto set_auto_reload(bool on_off) -> bool override;
  virtual auto is_auto_reload() -> bool override;
  virtual auto get_last_update_timestamp() -> std::time_t override;
  virtual auto is_modified_since(std::time_t ts) -> bool override;
  virtual auto row_count() -> std::size_t override;
  virtual auto get_row(std::size_t row) -> const CsvRow * override;
  virtual auto get_last_error() -> const std::string & override;
  /**
   * 热更新完成后进行数据源切换.
   *
   * \return
   */
  auto check_and_switch() -> void;
  /**
   * 获取文件路径.
   *
   * \return 文件路径
   */
  auto get_file_path() -> const std::string &;
  /**
   * 更新失败，回滚.
   *
   * \return
   */
  auto rollback() -> void;
  /**
   * 获取列数量.
   *
   * \return
   */
  auto col_count() -> std::size_t;
  /**
   * 获取容器
   */
  auto get_box() -> kratos::service::ServiceBox *;

private:
  /**
   * 解析.
   *
   * \param field_name 路径
   * \param is 文件流
   * \param row_vec 输出
   * \return true或false
   */
  auto parse(const std::string& file_path, std::istream &is, RowVector *row_vec) -> bool;
  /**
   * 存储错误描述.
   *
   * \param error 错误描述
   * \return
   */
  auto save_error(const std::string &error) -> void;

  /**
   * 读取csv每行数据
   *
   * \param row csv行数据
   * \param field 解析结果格子数据 可能会继承上一行没读完的数据
   * \param line 解析结果的行数据
   * \return true或false
   */
  auto read_csv_row(const std::string &row, std::string &field,
                    FieldVector & line) -> bool;

  /**
   * 收集格子信息插入到行信息当中
   * 
   * \param field 解析结果格子数据
   * \param line 解析结果的行数据
   * \return true或false
   */
  auto collect_field(std::string &field, FieldVector & line) -> bool;
};

/**
 * CSV热更新事件监听器句柄.
 */
class CsvListenrHandleImpl : public CsvListenrInternalHandle {
  std::uint32_t key_{0}; ///< 句柄内部标识

public:
  CsvListenrHandleImpl();
  virtual ~CsvListenrHandleImpl();
  /**
   * 获取内部标识.
   *
   * \return 内部标识
   */
  auto get_key() -> std::uint32_t;
};

/**
 * CSV管理器实现.
 */
class CsvManagerImpl : public CsvManager {
  using LoaderMap = kratos::service::PoolUnorederedMap<
      std::string, kratos::unique_pool_ptr<CsvLoaderImpl>>;
  using ListenerHandleWeakPtr = std::weak_ptr<CsvListenrInternalHandle>;
  struct ListenerInfo {
    std::string file_name;          ///< 文件名
    CsvFileChangeListener listener; ///< 监听器回调
    ListenerHandleWeakPtr handle;   ///< 监听器句柄
  };
  using ListenerMap =
      kratos::service::PoolUnorederedMap<std::uint32_t, ListenerInfo>;
  using TimeMap = kratos::service::PoolUnorederedMap<std::string, std::time_t>;
  using IgnoreSet = kratos::service::PoolUnorderedSet<std::string>;
  LoaderMap loader_map_;     ///< {文件名，加载器}
  ListenerMap listener_map_; ///< {监听器句柄，监听器信息}
  TimeMap time_map_;         ///< {文件名, 最新的修改时间}
  IgnoreSet ignore_set_;     ///< 忽略的文件
  std::thread worker_;       ///< 热更新线程
  std::string root_dir_;     ///< 根路径
  bool running_{false};      ///< 运行标志

  constexpr static std::time_t DEFAULT_INTERVAL = 60; ///< 默认检查周期，秒

  std::time_t check_interval_{DEFAULT_INTERVAL}; ///< 检查周期
  kratos::service::ServiceBox *box_{nullptr};    ///< 服务容器
  CsvReaderFactory *reader_factory_{nullptr};    ///< 读取器工厂

  kratos::corelib::SPSCQueue<CsvLoaderImpl *>
      update_event_queue_; ///< 热更新通知队列

public:
  CsvManagerImpl(kratos::service::ServiceBox *box);
  virtual ~CsvManagerImpl();
  virtual auto start(std::time_t check_interval = 60) -> bool override;
  virtual auto stop() -> bool override;
  virtual auto update() -> void override;
  virtual auto add_listener(const std::string &file_name,
                            CsvFileChangeListener listener)
      -> ListenerHandle override;
  virtual auto remove_listener(ListenerHandle handle) -> bool override;
  virtual auto set_root_directory(const std::string &root_dir) -> bool override;
  virtual auto set_file_auto_reload(const std::string &file_path, bool on_off)
      -> bool override;
  virtual auto
  new_reader(const std::string &file_name,
             const FieldDescriptor &descriptor = EmptyFieldDescriptor)
      -> std::unique_ptr<CsvReader> override;
  virtual auto new_reader(const std::string &file_name,
                          bool use_first_row_as_descriptor)
      -> std::unique_ptr<CsvReader> override;
  virtual auto set_reader_factory(CsvReaderFactory *factory)
      -> CsvReaderFactory * override;
  virtual auto ignore(const std::string &file_name) -> void override;

private:
  /**
   * 加载根目录内的所有文件.
   *
   * \return
   */
  auto load_all_files() -> bool;
};

/**
 * 游标实现.
 */
class CursorImpl : public Cursor {
  ResultImpl *result_{nullptr}; ///< 结果集
  std::size_t cur_index_{0};    ///< 当前行序号
  const FieldDescriptor *descriptor_{nullptr};

public:
  /**
   * 构造.
   *
   * \param result 查询结果
   */
  CursorImpl(ResultImpl *result);
  /**
   * 析构.
   *
   */
  virtual ~CursorImpl();
  virtual auto row_count() const noexcept -> std::size_t override;
  virtual auto column() const noexcept -> std::size_t override;
  virtual auto has_next() const noexcept -> bool override;
  virtual auto next() const -> void override;
  virtual operator bool() const override;
  virtual auto get(std::size_t col, std::string &value) const noexcept
      -> bool override;
  virtual auto get(std::size_t col,
                   std::vector<std::string> &value) const noexcept
      -> bool override;
  virtual auto
  get(std::size_t col,
      std::unordered_map<std::string, std::string> &value) const noexcept
      -> bool override;
  virtual auto get(std::size_t col,
                   std::unordered_set<std::string> &value) const noexcept
      -> bool override;
  virtual auto get(std::size_t col,
                   std::map<std::string, std::string> &value) const noexcept
      -> bool override;
  virtual auto get(std::size_t col, std::set<std::string> &value) const noexcept
      -> bool override;
  virtual void reset() const override;
  virtual auto get(const std::string &field_name,
                   std::string &value) const noexcept -> bool override;

  virtual auto get(const std::string &field_name,
                   std::vector<std::string> &value) const noexcept
      -> bool override;
  virtual auto
  get(const std::string &field_name,
      std::unordered_map<std::string, std::string> &value) const noexcept
      -> bool override;
  virtual auto get(const std::string &field_name,
                   std::unordered_set<std::string> &value) const noexcept
      -> bool override;
  virtual auto get(const std::string &field_name,
                   std::map<std::string, std::string> &value) const noexcept
      -> bool override;
  virtual auto get(const std::string &field_name,
                   std::set<std::string> &value) const noexcept
      -> bool override;

public:
  auto set_descriptor(const FieldDescriptor *descriptor) -> void;
  void set_result(ResultImpl *result);
};

/**
 * 查询结果.
 */
class ResultImpl : public Result {
  SearchResult search_result_;                  ///< 结果集
  unique_pool_ptr<CursorImpl> cursor_{nullptr}; ///< 游标
  bool success_{true};                          ///< 是否成功
  CsvReaderDefault *reader_{nullptr};

  ResultImpl(const ResultImpl &) = delete;
  const ResultImpl &operator=(const ResultImpl &) = delete;
  const ResultImpl &operator=(ResultImpl &&) = delete;

public:
  /**
   * 构造.
   *
   * \param reader CSV Reader
   * \param search_result 结果集
   * \param success 是否成功
   */
  ResultImpl(CsvReaderDefault *reader, SearchResult &&search_result,
             bool success);
  /**
   * 右值构造.
   *
   * \param rht 另一个实例
   * \return
   */
  ResultImpl(ResultImpl &&rht) noexcept;
  virtual auto get_cursor() const noexcept -> const Cursor & override;
  virtual operator bool() const override;
  /**
   * 获取结果集行数量.
   *
   * \return 结果集行数量
   */
  auto get_row() const -> std::size_t;
  /**
   * 获取结果集列数量.
   *
   * \return 结果集列数量
   */
  auto get_col() const -> std::size_t;
  /**
   * 获取结果集.
   *
   * \return 结果集
   */
  auto get_search_result() const -> const SearchResult &;
  /**
   * 清理.
   *
   * \return
   */
  auto clear() -> void;
};

/**
 * 读取器默认实现.
 * 数组格式: a;b;c;d
 * 字典格式: a:b;c:d
 * 集合格式: a:b:c:d
 */
class CsvReaderDefault : public CsvReader {
  using SearchCache =
      std::unordered_map<std::string, std::vector<const CsvRow *>>;
  using QueryCache = std::unordered_map<std::string, ResultImpl>;
  using RowCache = std::unordered_map<std::size_t, ResultImpl>;
  /**
   * 索引.
   */
  struct Index {
    std::string index_name;             ///< 索引名称
    std::size_t column{0};              ///< 索引对应的列
    std::type_info *type_info{nullptr}; ///< 索引建立时用户设置的列数据类型
    SearchCache search_cache;           ///< 通过索引进行查询的缓存
  };
  using IndexVector = std::vector<Index>;
  IndexVector index_vector_;                     ///< 索引数组
  QueryCache query_cache_;                       ///< 查询缓存
  RowCache row_cache_;                           ///< 行查询缓存
  CsvManagerImpl *manager_{nullptr};             ///< 管理器
  CsvLoaderImpl *loader_{nullptr};               ///< 加载器
  std::string last_error_;                       ///< 最新的错误
  std::string file_name_;                        ///< 文件名
  std::unique_ptr<ResultImpl> all_row_{nullptr}; ///< 全文
  FieldDescriptor descriptor_;                   ///< 列描述
  ListenerHandle listener_handler_{nullptr};     ///< 热更新监听
  std::size_t skip_line_{0}; ///< 保留不读取的前面行数

public:
  /**
   * 构造.
   *
   * \param loader 加载器
   */
  CsvReaderDefault(CsvManagerImpl *manager, CsvLoaderImpl *loader);
  /**
   * 析构.
   *
   */
  virtual ~CsvReaderDefault();
  virtual auto get_row() const noexcept -> std::size_t;
  virtual auto get_column() const noexcept -> std::size_t;
  virtual auto create_index_by_type(std::size_t col,
                                    const std::string &index_name,
                                    const std::type_info *type_info) noexcept
      -> bool override;
  virtual auto find_all() noexcept -> const Result & override;
  virtual auto find(std::initializer_list<CsvQuery> query) noexcept
      -> const Result & override;
  virtual auto find(std::initializer_list<std::any> query_key) noexcept
      -> const Result & override;
  virtual auto get(std::size_t row) noexcept -> const Result & override;
  virtual auto get(std::size_t row, std::size_t col,
                   std::string &value) noexcept -> bool override;
  virtual auto get(std::size_t row, std::size_t col,
                   std::vector<std::string> &value) noexcept -> bool override;
  virtual auto get(std::size_t row, std::size_t col,
                   std::unordered_map<std::string, std::string> &value) noexcept
      -> bool override;
  virtual auto get(std::size_t row, std::size_t col,
                   std::unordered_set<std::string> &value) noexcept
      -> bool override;
  virtual auto get(std::size_t row, std::size_t col,
                   std::map<std::string, std::string> &value) noexcept
      -> bool override;
  virtual auto get(std::size_t row, std::size_t col,
                   std::set<std::string> &value) noexcept -> bool override;
  virtual auto get_last_error() noexcept -> const std::string & override;
  virtual auto rebuild_index() noexcept -> bool override;
  virtual auto set_descriptor(const FieldDescriptor &descriptor)
      -> void override;
  virtual auto get_descriptor() const -> const FieldDescriptor & override;
  virtual auto set_skip_line(std::size_t skip_line) const -> void override;

private:
  /**
   * 获取全文.
   *
   * \return
   */
  auto get_all() noexcept -> const Result &;
};

} // namespace util
} // namespace kratos
